package wxpay

import (
	// "api/utils"
	"bytes"
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	uuid "github.com/satori/go.uuid"
)

type RefundReq struct {
	AppId       string `xml:"appid"`
	MchId       string `xml:"mch_id"`
	NonceStr    string `xml:"nonce_str"`
	OutTradeNo  string `xml:"out_trade_no"`
	Sign        string `xml:"sign"`
	OutRefundNo string `xml:"out_refund_no"`
	TotalFee    int    `xml:"total_fee"`
	RefundFee   int    `xml:"refund_fee"`
}

func WxRefund(appId string, orderCode string, refundFee int, totalFee int) (WxPayResponse, error) {
	var refundReq RefundReq
	refundReq.AppId = appId
	refundReq.MchId = MchId
	sourceUuid := uuid.NewV4()
	formatUuid := strings.Replace(sourceUuid.String(), "-", "", -1)
	refundReq.NonceStr = formatUuid
	refundReq.OutTradeNo = orderCode

	snowNode := fmt.Sprintf(`%16d`, time.Now().UnixMicro())
	// snowNode, err := utils.GetSnowNode()
	// if err != nil {
	// 	return WxPayResponse{}, err
	// }

	uidString := snowNode // strconv.FormatInt(snowNode.GetId(), 10)

	refundReq.OutRefundNo = "L" + uidString
	refundReq.RefundFee = refundFee
	refundReq.TotalFee = totalFee

	mReqMap := map[string]interface{}{}
	// mReqMap = make(map[string]interface{}, 0)
	mReqMap["appid"] = refundReq.AppId
	mReqMap["mch_id"] = refundReq.MchId
	mReqMap["nonce_str"] = refundReq.NonceStr
	mReqMap["out_trade_no"] = refundReq.OutTradeNo
	mReqMap["out_refund_no"] = refundReq.OutRefundNo
	mReqMap["total_fee"] = refundReq.TotalFee
	mReqMap["refund_fee"] = refundReq.RefundFee
	refundReq.Sign = WxPayCalcSign(mReqMap, MchSecret)

	xmlReq, err := xml.Marshal(refundReq)
	if err != nil {
		return WxPayResponse{}, err
	}
	strReq := string(xmlReq)
	strReq = strings.Replace(strReq, "RefundReq", "xml", -1)
	xmlReq = []byte(strReq)

	request, err := http.NewRequest("POST", "https://api.mch.weixin.qq.com/secapi/pay/refund", bytes.NewReader(xmlReq))
	if err != nil {
		return WxPayResponse{}, err
	}
	request.Header.Set("Accept", "application/xml")
	request.Header.Set("Content-Type", "application/xml;charset=utf-8")

	httpClient := http.Client{}
	response, err := httpClient.Do(request)
	if err != nil {
		return WxPayResponse{}, err
	}

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return WxPayResponse{}, err
	}

	var payResponse WxPayResponse
	err = xml.Unmarshal(responseBody, &payResponse)
	if err != nil {
		return WxPayResponse{}, err
	}

	return payResponse, nil
}
